package com.venus.finance.creditdebt.service.impl;

import java.util.Date;
import java.util.Iterator;
import java.util.List;

import com.venus.common.service.impl.BaseServiceImpl;
import com.venus.common.utils.ConditionUtil;
import com.venus.common.utils.Constants;
import com.venus.common.utils.DateUtil;
import com.venus.common.utils.MathUtil;
import com.venus.finance.account.dao.IAccountDAO;
import com.venus.finance.creditdebt.dao.ICreditDebtDAO;
import com.venus.finance.creditdebt.form.CreditDebtForm;
import com.venus.finance.creditdebt.service.ICreditDebtService;
import com.venus.model.AccountVO;
import com.venus.model.CreditDebtListVO;
import com.venus.model.CreditDebtVO;
import com.venus.model.PubUserVO;
import com.venus.pub.pubuser.dao.IPubUserDAO;

public class CreditDebtServiceImpl extends BaseServiceImpl implements ICreditDebtService {

	private ICreditDebtDAO creditDebtDAO ;
	
	private IAccountDAO accountDAO;
	
	private IPubUserDAO pubUserDAO;

	public void setCreditDebtDAO(ICreditDebtDAO creditDebtDAO) {
		this.creditDebtDAO = creditDebtDAO;
	}
	
	public void setAccountDAO(IAccountDAO accountDAO) {
		this.accountDAO = accountDAO;
	}
	
	public void setPubUserDAO(IPubUserDAO pubUserDAO) {
		this.pubUserDAO = pubUserDAO;
	}

	@SuppressWarnings("unchecked")
	public List<CreditDebtVO> findAllCreditDebt(List<ConditionUtil> lstConditionUtils) {
		return this.creditDebtDAO.exeHql("from CreditDebtVO where 1=1 ", lstConditionUtils);
	}

	public CreditDebtVO findCreditDebtVO(Integer iCreditDebtId) {
		return this.creditDebtDAO.getModel(CreditDebtVO.class, iCreditDebtId);
	}
	
	public void saveOrUpdateCreditDebt(CreditDebtVO creditDebt) {
		this.creditDebtDAO.saveOrUpdateModel(creditDebt);
	}
	
	// 新增债权信息
	public int saveCreditDebt(CreditDebtForm objCreditDebtForm) {
		CreditDebtVO objCreditDebtVO = new CreditDebtVO();
		PubUserVO objPubUserVO = this.pubUserDAO.getModel(PubUserVO.class, objCreditDebtForm.getCreatorId());
		objCreditDebtVO.setCreator(objPubUserVO);
		objCreditDebtVO.setCreditor(objCreditDebtForm.getCreditor());
		objCreditDebtVO.setDebtor(objCreditDebtForm.getDebtor());
		objCreditDebtVO.setAmount(objCreditDebtForm.getAmount());
		objCreditDebtVO.setInterest(objCreditDebtForm.getInterest());
		objCreditDebtVO.setPaidAmount(0f);
		objCreditDebtVO.setPaidInterest(0f);
		objCreditDebtVO.setLoanDate(DateUtil.stringToUtilDate(objCreditDebtForm.getLoanDate(), "yyyy-MM-dd"));
		objCreditDebtVO.setDeadlineDate(DateUtil.stringToUtilDate(objCreditDebtForm.getDeadlineDate(), "yyyy-MM-dd"));
		objCreditDebtVO.setNote(objCreditDebtForm.getNote());
		if(Constants.CREDITDEBT_CREDIT == objCreditDebtForm.getCreditOrDebt()){ // 债权
			objCreditDebtVO.setCreditOrDebt(Constants.CREDITDEBT_CREDIT);
			// 支出账户减去支出金额
			AccountVO outAccountVO = this.accountDAO.getModel(AccountVO.class, objCreditDebtForm.getOutAccountId());
			outAccountVO.setAmount(MathUtil.round(outAccountVO.getAmount() - objCreditDebtForm.getAmount(), 2).floatValue());
			objCreditDebtVO.setOutAccount(outAccountVO);
			// 更新账户余额
			this.accountDAO.saveOrUpdateModel(outAccountVO );
		}else if(Constants.CREDITDEBT_DEBT == objCreditDebtForm.getCreditOrDebt()){// 债务
			objCreditDebtVO.setCreditOrDebt(Constants.CREDITDEBT_DEBT);
			// 支出账户减去支出金额
			AccountVO inAccountVO = this.accountDAO.getModel(AccountVO.class, objCreditDebtForm.getInAccountId());
			inAccountVO.setAmount(MathUtil.round(inAccountVO.getAmount() + objCreditDebtForm.getAmount(), 2).floatValue());
			objCreditDebtVO.setInAccount(inAccountVO);
			// 更新账户余额
			this.accountDAO.saveOrUpdateModel(inAccountVO );
		}
		// 保存债券信息
		this.saveOrUpdateCreditDebt(objCreditDebtVO);
		return objCreditDebtVO.getCreditDebtId();
	}
	
	// 修改债权信息
	public int editCreditDebt(CreditDebtForm objCreditDebtForm) {
		// 得到待修改的实例
		CreditDebtVO objCreditDebtVO = this.findCreditDebtVO(objCreditDebtForm.getCreditDebtId());
		PubUserVO objPubUserVO = this.pubUserDAO.getModel(PubUserVO.class, objCreditDebtForm.getCreatorId());
		objCreditDebtVO.setCreator(objPubUserVO);
		objCreditDebtVO.setCreditor(objCreditDebtForm.getCreditor());
		objCreditDebtVO.setDebtor(objCreditDebtForm.getDebtor());
		objCreditDebtVO.setAmount(objCreditDebtForm.getNewAmount());
		objCreditDebtVO.setInterest(objCreditDebtForm.getNewInterest());
		objCreditDebtVO.setLoanDate(DateUtil.stringToUtilDate(objCreditDebtForm.getLoanDate(), "yyyy-MM-dd"));
		objCreditDebtVO.setDeadlineDate(DateUtil.stringToUtilDate(objCreditDebtForm.getDeadlineDate(), "yyyy-MM-dd"));
		objCreditDebtVO.setNote(objCreditDebtForm.getNote());
		if(Constants.CREDITDEBT_CREDIT == objCreditDebtForm.getCreditOrDebt()){ // 债权
			// 更改了账户要先将支出金额加回原始支出账号,再从新的账号减去
			if(objCreditDebtForm.getOutAccountId() != objCreditDebtForm.getNewOutAccountId()){ // 支出账户有改变
				// 原始支出账户:支出账户余额+原始支出金额
				AccountVO outAccountVO = this.accountDAO.getModel(AccountVO.class, objCreditDebtForm.getOutAccountId());
				outAccountVO.setAmount(MathUtil.round(outAccountVO.getAmount() + objCreditDebtForm.getAmount(), 2).floatValue());
				// 更新原始账户余额
				this.accountDAO.saveOrUpdateModel(outAccountVO);
				// 新支出账户:支出账户余额-新支出金额
				AccountVO newOutAccountVO = this.accountDAO.getModel(AccountVO.class, objCreditDebtForm.getNewOutAccountId());
				newOutAccountVO.setAmount(MathUtil.round(newOutAccountVO.getAmount() - objCreditDebtForm.getNewAmount(), 2).floatValue());
				objCreditDebtVO.setOutAccount(newOutAccountVO);
				// 更新新账户余额
				this.accountDAO.saveOrUpdateModel(newOutAccountVO);
			}else{ // 支出账户没有改变
				// 支出账户:支出账户余额+原始支出金额-新支出金额
				AccountVO newOutAccountVO = this.accountDAO.getModel(AccountVO.class, objCreditDebtForm.getNewOutAccountId());
				newOutAccountVO.setAmount(MathUtil.round(newOutAccountVO.getAmount() + objCreditDebtForm.getAmount() - objCreditDebtForm.getNewAmount(), 2).floatValue());
				objCreditDebtVO.setOutAccount(newOutAccountVO);
				// 更新账户余额
				this.accountDAO.saveOrUpdateModel(newOutAccountVO);
			}
		}else if(Constants.CREDITDEBT_DEBT == objCreditDebtForm.getCreditOrDebt()){ // 债务
			// 更改了账户要先将收入金额减回原始收入账号,再从新的账号加上金额
			if(objCreditDebtForm.getInAccountId() != objCreditDebtForm.getNewInAccountId()){ // 支出账户有改变
				// 原始收入账户:收入账户余额-原始收入金额
				AccountVO inAccountVO = this.accountDAO.getModel(AccountVO.class, objCreditDebtForm.getInAccountId());
				inAccountVO.setAmount(MathUtil.round(inAccountVO.getAmount() - objCreditDebtForm.getAmount(), 2).floatValue());
				// 更新原始账户余额
				this.accountDAO.saveOrUpdateModel(inAccountVO);
				// 新收入账户:收入账户余额+新收入金额
				AccountVO newInAccountVO = this.accountDAO.getModel(AccountVO.class, objCreditDebtForm.getNewInAccountId());
				newInAccountVO.setAmount(MathUtil.round(newInAccountVO.getAmount() + objCreditDebtForm.getNewAmount(), 2).floatValue());
				objCreditDebtVO.setInAccount(newInAccountVO);
				// 更新新账户余额
				this.accountDAO.saveOrUpdateModel(newInAccountVO);
			}else{ // 收入账户没有改变
				// 收入账户:收入账户余额-原始收入金额+新收入金额
				AccountVO newInAccountVO = this.accountDAO.getModel(AccountVO.class, objCreditDebtForm.getNewInAccountId());
				newInAccountVO.setAmount(MathUtil.round(newInAccountVO.getAmount() - objCreditDebtForm.getAmount() + objCreditDebtForm.getNewAmount(), 2).floatValue());
				objCreditDebtVO.setOutAccount(newInAccountVO);
				// 更新账户余额
				this.accountDAO.saveOrUpdateModel(newInAccountVO);
			}
		}
		// 保存信息
		this.saveOrUpdateCreditDebt(objCreditDebtVO);
		return objCreditDebtVO.getCreditDebtId();
	}
	
	// 删除债权债务信息
	@SuppressWarnings("unchecked")
	public void deleteCreditDebt(String[] strCreditDebtIds) {
		for(String strCreditDebtId : strCreditDebtIds){
			// 主单实例
			CreditDebtVO objCreditDebtVO = this.findCreditDebtVO(Integer.parseInt(strCreditDebtId));
			// 循环主单实例的明细,删除明细
			for(Iterator<CreditDebtListVO> iterCreditDebtListVOs = objCreditDebtVO.getCreditDebtList().iterator();iterCreditDebtListVOs.hasNext();){
				CreditDebtListVO objCreditDebtListVO = iterCreditDebtListVOs.next();
				AccountVO objCreditDebtListAccount = objCreditDebtListVO.getAccount();
				// 删除明细的同时,判断类型,债权在接收账户的基础上减去金额,债务则是加上金额
				if(Constants.CREDITDEBT_CREDIT == objCreditDebtVO.getCreditOrDebt()){ // 减已还金额
					objCreditDebtListAccount.subAmount(MathUtil.round(objCreditDebtListVO.getAmount() + objCreditDebtListVO.getInterest(), 2).floatValue());
				}else if(Constants.CREDITDEBT_DEBT == objCreditDebtVO.getCreditOrDebt()){ // 加已还余额
					objCreditDebtListAccount.addAmount(MathUtil.round(objCreditDebtListVO.getAmount() + objCreditDebtListVO.getInterest(), 2).floatValue());
				}
				// 保存账户信息
				this.accountDAO.saveOrUpdateModel(objCreditDebtListAccount);
				// 删除债权债务明细
				this.creditDebtDAO.deleteModel(objCreditDebtListVO);
			}
			// 判断类型,债权主单实例的支出账户加上借出金额,债务则是收入账户减去借入金额
			if(Constants.CREDITDEBT_CREDIT == objCreditDebtVO.getCreditOrDebt()){
				AccountVO objOutAccountVO = objCreditDebtVO.getOutAccount();
				objOutAccountVO.addAmount(objCreditDebtVO.getAmount());
				// 保存借出账户
				this.accountDAO.saveOrUpdateModel(objOutAccountVO);
			}else if(Constants.CREDITDEBT_DEBT == objCreditDebtVO.getCreditOrDebt()){
				AccountVO objInAccountVO = objCreditDebtVO.getInAccount();
				objInAccountVO.subAmount(objCreditDebtVO.getAmount());
				// 保存借入账户
				this.accountDAO.saveOrUpdateModel(objInAccountVO);
			}
			// 删除债权信息
			this.creditDebtDAO.deleteModel(objCreditDebtVO);
		}
	}
	
	// 快速债权收账,债务还款
	public void updateCreditDebtAmount(CreditDebtForm objCreditDebtForm) {
		// 得到债权实例
		CreditDebtVO objCreditDebtVO = this.findCreditDebtVO(objCreditDebtForm.getCreditDebtId());
		// 更新债权信息
		objCreditDebtVO.addPaidAmount(objCreditDebtForm.getPaidAmount());
		objCreditDebtVO.addPaidInterest(objCreditDebtForm.getPaidInterest());
		this.saveOrUpdateCreditDebt(objCreditDebtVO);
		AccountVO objAccountVO = null;
		if(Constants.CREDITDEBT_CREDIT == objCreditDebtForm.getCreditOrDebt()){ // 债权
			// 更新收账账户信息
			objAccountVO = this.accountDAO.getModel(AccountVO.class, objCreditDebtForm.getInAccountId());
			// 余额+收款金额+收款利息
			objAccountVO.setAmount(MathUtil.round(objAccountVO.getAmount()+objCreditDebtForm.getPaidAmount()+objCreditDebtForm.getPaidInterest(), 2).floatValue());
		}else if(Constants.CREDITDEBT_DEBT == objCreditDebtForm.getCreditOrDebt()){ // 债务
			// 更新收账账户信息
			objAccountVO = this.accountDAO.getModel(AccountVO.class, objCreditDebtForm.getOutAccountId());
			// 余额-还款金额-还款利息
			objAccountVO.setAmount(MathUtil.round(objAccountVO.getAmount()-objCreditDebtForm.getPaidAmount()-objCreditDebtForm.getPaidInterest(), 2).floatValue());
		}
		this.accountDAO.saveOrUpdateModel(objAccountVO);
		// 新增收款明细
		CreditDebtListVO objCreditDebtListVO = new CreditDebtListVO();
		objCreditDebtListVO.setAccount(objAccountVO);
		objCreditDebtListVO.setAmount(objCreditDebtForm.getPaidAmount());
		objCreditDebtListVO.setInterest(objCreditDebtForm.getPaidInterest());
		objCreditDebtListVO.setCreditDebt(objCreditDebtVO);
		objCreditDebtListVO.setPayDate(new Date());
		objCreditDebtListVO.setNote("");
		this.creditDebtDAO.saveOrUpdateModel(objCreditDebtListVO);
	}

	// 更新债权债务明细
	@SuppressWarnings("unchecked")
	public void updateCreditDebtList(int strCreditDebtId, String[] strPayDates, String[] strAccountIds, String[] strAmounts, String[] strInterests, String[] strNotes) {
		// 主单实例
		CreditDebtVO objCreditDebtVO = this.findCreditDebtVO(strCreditDebtId);
		// 删除债权债务明细,还原账户余额
		for(Iterator<CreditDebtListVO> iterCreditDebtListVOs = objCreditDebtVO.getCreditDebtList().iterator();iterCreditDebtListVOs.hasNext();){
			CreditDebtListVO objCreditDebtListVO = iterCreditDebtListVOs.next();
			// 还原主单的收还款余额,还原关联账户的钱
			if(Constants.CREDITDEBT_CREDIT == objCreditDebtVO.getCreditOrDebt()){ // 减已还金额
				objCreditDebtVO.subPaidAmount(objCreditDebtListVO.getAmount());
				objCreditDebtVO.subPaidInterest(objCreditDebtListVO.getInterest());
				objCreditDebtListVO.getAccount().subAmount(MathUtil.round(objCreditDebtListVO.getAmount() + objCreditDebtListVO.getInterest(), 2).floatValue());
			}else if(Constants.CREDITDEBT_DEBT == objCreditDebtVO.getCreditOrDebt()){// 加已还余额
				objCreditDebtVO.subPaidAmount(objCreditDebtListVO.getAmount());
				objCreditDebtVO.subPaidInterest(objCreditDebtListVO.getInterest());
				objCreditDebtListVO.getAccount().addAmount(MathUtil.round(objCreditDebtListVO.getAmount() + objCreditDebtListVO.getInterest(), 2).floatValue());
			}
			// 删除债权债务明细
			this.creditDebtDAO.deleteModel(objCreditDebtListVO);
		}
		if(strAccountIds!=null){
			// 债权:账户金额加上接收的金额,债务:账户金额减去支出的金额
			for(int i=0;i<strAccountIds.length;i++){
				AccountVO objAccountVO = this.accountDAO.getModel(AccountVO.class, Integer.parseInt(strAccountIds[i]));
				// 准备新增明细实例
				CreditDebtListVO objCreditDebtListVO = new CreditDebtListVO();
				objCreditDebtListVO.setAccount(objAccountVO);
				objCreditDebtListVO.setCreditDebt(objCreditDebtVO);
				objCreditDebtListVO.setPayDate(DateUtil.stringToUtilDate(strPayDates[i], "yyyy-MM-dd"));
				objCreditDebtListVO.setAmount(Float.valueOf(strAmounts[i]));
				objCreditDebtListVO.setInterest(Float.valueOf(strInterests[i]));
				objCreditDebtListVO.setNote(strNotes[i]);
				// 保存明细实例
				this.creditDebtDAO.saveModel(objCreditDebtListVO);
				// 更新账户信息:债权加余额,债务减余额
				if(Constants.CREDITDEBT_CREDIT == objCreditDebtVO.getCreditOrDebt()){ // 加账户余额
					objAccountVO.addAmount(Float.valueOf(strAmounts[i]));// 借款额
					objAccountVO.addAmount(Float.valueOf(strInterests[i]));// 利息
				}else if(Constants.CREDITDEBT_DEBT == objCreditDebtVO.getCreditOrDebt()){// 减账户余额
					objAccountVO.subAmount(Float.valueOf(strAmounts[i]));// 借款额
					objAccountVO.subAmount(Float.valueOf(strInterests[i]));// 利息
				}
				// 更新账户实例
				this.accountDAO.updateModel(objAccountVO);
				// 支付款明细金额累加到主单实例上
				objCreditDebtVO.addPaidAmount(Float.valueOf(strAmounts[i]));
				objCreditDebtVO.addPaidInterest(Float.valueOf(strInterests[i]));
			}
		}
		// 更新债权债务主实例
		this.creditDebtDAO.updateModel(objCreditDebtVO);
	}
	
}
